#include <systemc.h>  // 核心 SystemC 库

// [定义一个 SystemC 模块 (Module)]
// SC_MODULE 是一个宏, 用于方便地声明一个 SystemC 模块类. 
// SC_MODULE(HelloWorld) 等价于 struct HelloWorld : public sc_module
SC_MODULE(HelloWorld) {
    // [定义一个成员函数, 其将作为 SystemC 进程 (Process) 的主体]
    // 进程是 SystemC 中执行并发活动的基本单元. 
    void say_hello() {
        // sc_time_stamp() 返回当前的仿真时间. 
        // name() 返回模块的名称.
        std::cout << "@" << sc_time_stamp() << ": Hello SystemC World!" << " From " << name() <<std::endl;
        printf("%s @ %s: Hello SystemC World!\n", name(), sc_time_stamp().to_string().c_str());
        // 此进程只执行一次打印操作, 随后便结束. 
    }

    // [定义模块的构造函数 (Constructor)]
    // SC_CTOR 是一个宏, 用于定义模块的构造函数. 其只能有一个参数, 即模块类的名称.
    // 构造函数在模块实例化时被调用, 用于设置模块内部结构和注册进程. 
    SC_CTOR(HelloWorld) {
        // [注册进程 (Process Registration)]
        // SC_THREAD 宏用于将成员函数 'say_hello' 注册为一个 SC_THREAD 进程. 
        // SC_THREAD  进程在仿真开始时执行一次. 
        // 如果没有使用 wait() 或敏感列表, 它会执行完所有语句然后终止. 
        // 其他类型的进程还有 SC_METHOD (用于组合逻辑) 和 SC_CTHREAD (时钟同步线程). 
        SC_THREAD(say_hello);
        // 对于此例, 不需要为 SC_THREAD 指定敏感列表 (sensitivity list), 它会在仿真时间 0 开始执行. 
    }

}; // 模块定义结束

// [定义 sc_main 函数 - SystemC 仿真的入口点]
// SystemC 程序使用 sc_main 而不是标准的 main 函数. 
// SystemC 库本身提供的 main 函数会调用 sc_main 函数. 
int sc_main(int argc, char* argv[]) {

    std::cout << "Info: Starting SystemC simulation." << std::endl;

    // [实例化 (Instantiate) 定义的模块]
    // 创建 HelloWorld 模块的一个实例, 并给它一个名称 "hello_world". 
    // 实例名称在调试和波形跟踪时很有用. 
    HelloWorld hello_world("hello_world");

    // [启动仿真 (Start Simulation)]
    // sc_start() 函数启动 SystemC 仿真内核. 
    // 如果不带参数调用, 仿真会一直运行, 直到没有更多的事件需要处理, 或者直到 sc_stop() 被显式调用. 
    // 在这个例子中, 'say_hello' 进程在时间 0 执行并结束, 之后没有其他事件, 所以仿真会很快停止. 
    // 也可以指定一个仿真时间, 例如 sc_start(10, SC_NS) 来运行 10 纳秒. 
    sc_start();

    std::cout << "Info: SystemC simulation finished." << std::endl;

    // [sc_main 必须返回 0 表示成功退出] 
    return 0;
}
